/**
 * ReportGear(2011)
 */
package com.reportgear.report.view.grid.editor.impl;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

import com.reportgear.report.core.background.ColorBackground;
import com.reportgear.report.model.cell.Cell;
import com.reportgear.report.model.cell.style.FontStyle;
import com.reportgear.report.model.cell.style.HorizentalAlignment;
import com.reportgear.report.model.cell.style.Style;
import com.reportgear.report.view.grid.Grid;
import com.reportgear.report.view.grid.editor.AbstractCellEditor;
import com.sot.core.util.StringUtils;

/**
 * 通用单元格编辑器
 * 
 * @version 1.0 2011-3-22
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since report 1.0
 */
public final class GeneralCellEditor extends AbstractCellEditor {
	private static class EditTextField extends JTextField {
		/**
		 * UID
		 */
		private static final long serialVersionUID = -7511032788987277080L;

		private class TextDocument extends PlainDocument {
			/**
			 * UID
			 */
			private static final long serialVersionUID = -2538363677151823062L;

			@Override
			public void insertString(int offs, String string, AttributeSet attSet) throws BadLocationException {
				final String str = this.getText(0, this.getLength());
				if ((str != null) && (str.length() > EditTextField.this.getMaxLength())) {
					Toolkit.getDefaultToolkit().beep();
					return;
				}
				super.insertString(offs, string, attSet);
			}
		}

		/**
		 * 最长字符宽度
		 */
		private int maxLength;

		public EditTextField() {
			this(10000);
		}

		public EditTextField(int maxLength) {
			this.maxLength = maxLength;
			this.setDocument(new TextDocument());
		}

		public int getMaxLength() {
			return this.maxLength;
		}

		public void setMaxLength(int maxLength) {
			this.maxLength = maxLength;
		}
	}

	/**
	 * 单元格对象
	 */
	private Grid grid;
	private EditTextField textField = new EditTextField();
	private String oldValue = "";
	private KeyListener textKeyListener = new KeyListener() {

		public void keyTyped(KeyEvent keyEvent) {
			ajustTextFieldSize();
		}

		public void keyPressed(KeyEvent evt) {
			int keyCode = evt.getKeyCode();
			if (keyCode == KeyEvent.VK_ESCAPE) {
				textField.setText(oldValue);
				evt.consume();
			} else {
				if ((keyCode != KeyEvent.VK_ENTER) && (keyCode != KeyEvent.VK_TAB) && (keyCode != KeyEvent.VK_UP)
						&& (keyCode != KeyEvent.VK_DOWN)) {
					return;
				}

				GeneralCellEditor.this.grid.requestFocus();
				GeneralCellEditor.this.grid.dispatchEvent(evt);
			}
		}

		public void keyReleased(KeyEvent evt) {
		}
	};

	public GeneralCellEditor() {
		this.textField.setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 1));
		this.textField.addKeyListener(this.textKeyListener);
		this.textField.addFocusListener(new FocusAdapter() {

			@Override
			public void focusLost(FocusEvent evt) {
				stopCellEditing();
			}
		});
		this.textField.setFocusTraversalKeysEnabled(false);
	}

	public int getMaxLength() {
		return this.textField.getMaxLength();
	}

	public void setMaxLength(int maxLen) {
		this.textField.setMaxLength(maxLen);
	}

	public Object getCellEditorValue() {
		return this.textField.getText();
	}

	public Component getCellEditorComponent(Grid grid, Cell cell) {
		this.grid = grid;
		Object value = cell.getValue();

		if (value == null) {
			value = "";
		}

//		if (!(value instanceof String) && !(value instanceof Number)) {
//			value = "";
//			cell.setValue("");
//		}

		this.oldValue = StringUtils.convertToString(value);
		this.textField.setText(this.oldValue);

		Style style = cell.getStyle();
		ajustTextStyle(grid, style, value);

		return this.textField;
	}

	protected void ajustTextStyle(JComponent component, Style style, Object obj) {
		if (style == null) {
			style = Style.DEFAULT_STYLE;
		}
		HorizentalAlignment hAlign = style.getHorizentalAlignment();
		if (hAlign == HorizentalAlignment.LEFT) {
			this.textField.setHorizontalAlignment(SwingConstants.LEFT);
		} else if (hAlign == HorizentalAlignment.CENTER) {
			this.textField.setHorizontalAlignment(SwingConstants.CENTER);
		} else if (hAlign == HorizentalAlignment.RIGHT) {
			this.textField.setHorizontalAlignment(SwingConstants.RIGHT);
		} else {
			this.textField.setHorizontalAlignment(SwingConstants.LEFT);
		}

		FontStyle font = style.getFontStyle();
		this.textField.setFont(new Font(font.getFontName(), font.getStyle(), font.getSize()));
		this.textField.setForeground(style.getFontStyle().getForeground());
		if (style.getBackground() instanceof ColorBackground) {
			this.textField.setBackground(((ColorBackground) style.getBackground()).getColor());
		} else {
			this.textField.setBackground(Color.WHITE);
		}
	}

	private void ajustTextFieldSize() {
		Dimension dim1 = this.textField.getSize();
		Dimension dim2 = this.textField.getPreferredSize();
		this.textField.setSize((int) Math.max(dim1.getWidth(), dim2.getWidth()), (int) dim1.getHeight());
	}
}
